using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Remoting.Channels.Tcp;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting;
using System.Runtime.Serialization.Formatters;
using System.Collections;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
using XNAProject.Ships;
using XNAProject.Core;
using System.Reflection;


namespace XNAProject.GameElements
{
    public class Player : Microsoft.Xna.Framework.GameComponent, IEnumerable<Ship>
    {
        public string name { get; set; }
        public bool host { get; set; }                                                       //props
        public bool turn { get; set; }
        private bool turnChange;
        private float time, previousTime = 0;
        public TimeSpan TimeLeft { get; set; }

        public int oil { get; set; }
        public int money { get; set; }

        public Fleet OwnFleet { get; set; }
        private ISynchronize synch;

        public Player(Game game): base(game)
        {
            oil = 2000;                                                                                 //constructor
            money = 6000;

            synch = new Synchronize();
            OwnFleet = new Fleet();
			turn = false;
            turnChange = false;
            TimeLeft = TimeSpan.Zero;
        }

        public override void Initialize()
        {
            base.Initialize();
        }

        public override void Update(GameTime gameTime)
        {
            time += (float)gameTime.ElapsedGameTime.Milliseconds / 1000;

            if (turn)
            {
                //if (turnChange)
                //    Synchronize();

                if (TimeLeft == TimeSpan.Zero)
                {
                    Level level = (Level)Game.Services.GetService(typeof(Level));
                    TimeLeft = level.TurnTime;
                }

                if (time - previousTime >= 1)
                {
                    previousTime++;
                    TimeLeft = new TimeSpan(0, 0, (int)(TimeLeft.TotalSeconds - 1));
                }

                if (TimeLeft == TimeSpan.Zero)
                {
                    turn = false;
                    turnChange = true;
                    ConsoleMenu console = (ConsoleMenu)Game.Services.GetService(typeof(ConsoleMenu));
                    console.ActionText("End of Turn!");
                }
            }
            else if (turnChange)
            {
                turnChange = false;
                //SetSynchronize();
            }
            else
            {
            }

            base.Update(gameTime);
        }

        #region Synchronize        

        //public void SetSynchronize()
        //{
        //    Level level = (Level)Game.Services.GetService(typeof(Level));

        //    SynchPack pack = new SynchPack();
        //    pack.synchFleet = OwnFleet;
        //    pack.synchLevel = level.hexagonCollection;

        //    synch.Send(pack);
        //}

        //public void Synchronize()
        //{
        //    Enemy enemy = (Enemy)Game.Services.GetService(typeof(Enemy));
        //    Level level = (Level)Game.Services.GetService(typeof(Level));
        //    synch = (ISynchronize)Activator.GetObject(typeof(ISynchronize), "tcp://192.168.1.109:9000/ISynchronize");

        //    enemy.OwnFleet = synch.GetPack().synchFleet;
        //    level.hexagonCollection = synch.GetPack().synchLevel;
        //}

        //public void FirstSynchronize()
        //{
        //    synch = (ISynchronize)Activator.GetObject(typeof(ISynchronize), "tcp://192.168.1.109:9000/ISynchronize");

        //    //synch = (ISynchronize)GetRemotingObject(typeof(ISynchronize));
        //}

        //public void StartServer()
        //{
        //    //BinaryServerFormatterSinkProvider provider = new BinaryServerFormatterSinkProvider();
        //    //provider.TypeFilterLevel = TypeFilterLevel.Full;
        //    //Hashtable props = new Hashtable();
        //    //props.Add("port", 9000);
        //    //props["name"] = "hah";
        //    //TcpChannel channel = new TcpChannel(props, null, provider);
        //    //ChannelServices.RegisterChannel(channel);

        //    TcpChannel channel = new TcpChannel(9000);
        //    ChannelServices.RegisterChannel(channel, false);
        //    RegisterRemotingObjects();
        //    //RemotingConfiguration.RegisterWellKnownServiceType(typeof(Synchronize), "ISynchronize", WellKnownObjectMode.SingleCall);

        //    //Synchronize synch = new Synchronize();
        //    //RemotingServices.Marshal(synch, "ISynchronize");
        //}

        //public static object GetRemotingObject(Type type)
        //{
        //    //return Activator.GetObject(type, "tcp://192.168.1.109:9000/" + type.Name);
        //    return Activator.GetObject(type, "tcp://localhost:9000/" + type.Name);
        //}

        //public static void RegisterRemotingObjects()
        //{
        //    Type[] types = Assembly.GetExecutingAssembly().GetModules()[0].GetTypes();
        //    foreach (Type type in types)
        //        if (type.IsSubclassOf(typeof(MarshalByRefObject)))
        //            RemotingConfiguration.RegisterWellKnownServiceType(type, "I" + type.Name, WellKnownObjectMode.SingleCall);

        //}

        #endregion

        #region Procedures

        public void ReSet()
        {
            oil = 0;
            money = 0;
            OwnFleet.EmptyFleet();
        }
		
		public void AddShip(Ship ship)
        {
            OwnFleet.Add(ship);
        }

        public IEnumerator<Ship> GetEnumerator()
        //so we can foreach through the players ships
        {
            foreach (Ship item in OwnFleet.shipCollection)
            {
                yield return item;
            }
        }

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        //not used atm but IEnumerable interface needs it
        {
            throw new NotImplementedException();
        }

        #endregion
    }
}